Home | | Latest | About | Random
# Week 4 Wednesday
Dear Class,
Today we start section 9, **fun with functions!** We will go through functions in several phases, first a simple overview, then more nuances of them in future lectures. Already with handling input/output, storing data, and control flow, you can write "all" programs a computer can perform. **Being able to write and use functions makes your program even more powerful! Often programs consist of mostly functions!**
Section 9 is not tested on Exam 1, but we continue to build everything up from what we have learned so far.
For Exam 1, I've started a [[1-teaching/ucla-2026-fall-pic-10a/laundry-list|laundry-list]] of things we've discussed. You should make yourself a laundry list as well. This of course is not enough, you should read and write code with them to practice! (**Perhaps you all can collaborate amongst yourselves and make a communal list**!)
Also, there will be **no notes, closed book, no technology, no cheating, no shenanigans** for the exam. Bring your own **pencil or pen**, as you will be writing your responses on sheets of paper provided to you. The exam is **50 minutes** in class, about **3 to 4 problems, some may have multiple parts.** It covers up to and including **section 8**, homework up to and including **HW3**, and the lectures we have done so far.
Your **HW3** is **due this Friday at 10pm**.
-- B.
.
.
.
.
**Here's a birthday card for anyone who has a birthday!**
![[1-teaching/ucla-2026-fall-pic-10a/---files/Pasted image 20261021070756.png]]
## Functions -- A first look.
### But first... Is it anyone's birthday?
**Raise your hand if your birthday is this month!**
Let's all sing happy birthday to them!
```
Happy birthday to you!
Happy birthday to you!
Happy birthday dear [their name]!
Happy birthday to you!
```
And again!
.
.
.
.
.
## Function to abstract away repeated task.
Suppose we want to write a program that sings happy birthday to each person `A`, `B`, `C`, ... with a birthday. It will be laborious to write out a song each time for each person individually. Not that we don't want to, of course...
So instead, we write a **function**, that is like a *factory* or *machine*, where it either **does something**, or **outputs something**, or **both**. In this case we take in the birthday star's name as input and we print a song out with their name!
Perhaps we call our function `sing`, and perhaps it takes in a `string` as input for a person's name, and all it does is print to the screen the song.
To accomplish what we want, we will discuss how to
- **Declare** a function,
- **Define** a function, and
- **Call** a function
.
.
.
.
.
## Declaring a function.
To do this, like a variable before, we have to **declare** it before we use it. And since we anticipate using it in `main`, we need to declare it before `main`, like this
```cpp
#include
#include
using namespace std;
void sing(string person); // declaring our function
int main() {
return 0;
}
```
Note the function `sing` has the word `void` in front of it, this is its **return type**.
- Often a function returns a value, so the type of the value goes in front of the name of the function when we declare it.
- This return value can be assigned to another variable later. You can think of this return value as the **output** of this function.
- `int my_function(...);` declares a function that will return an `int`.
- `string my_other_function(...);` declares a function that will return a `string`.
- To return the value `x`, we use the `return` keyword by writing `return x;`
- The function ends immediately when it reaches the `return` keyword, and control goes back to where the function was called.
- We will return to `return` later. Ha-ha!
- If the function does not return anything, then its return type is `void`. Our `sing` function will only perform an action (print to the console), but it will not give back a value.
Now, in this function declaration `void sing(string person);`, we also indicated the type of the input as well, in this case it is a `string`. The name of the input here is called `person`.
- This variable is called a **parameter** of this function.
- During declaration of a function, you do not need to specify the name of the parameter, just the type suffices. So `void sing(string);` is a valid declaration.
- This line `void sing(string person)` is also known as the **function signature** of this function. It tells us the (1) name of the function, (2) the return type of the function, and (3) the types and number of parameters for this function.
- According to the book, this is the function signature. (Which is fine for our purpose in our class.)
.
.
.
.
.
## Defining a function.
Now that we have declared our function `sing`, we need to **define** what it does. We use braces `{` and `}` to define the action of this function.
- You can **declare and define all together at the top**:
```cpp
#include
#include
using namespace std;
void sing(string person) { // declare and define together
// some action!
}
int main() {
return 0;
}
```
- Note when you define a function, you need to name the parameter if you want to use it inside the function body.
- Or, you can **declare** at the top first, then **define** the function later after the `main`:
```cpp
#include
#include
using namespace std;
void sing(string person); // declare first
int main() {
return 0;
}
void sing(string person) { // define later
// some action!
}
```
Ok, now let's write something that this `sing` function should do, namely, sing the happy birthday song to `person`!
```cpp
void sing(string person) {
for (int i = 0; i < 10; ++i){ cout << "~ * ";} cout << endl;
cout << "Happy birthday to you!" << endl;
cout << "Happy birthday to you!" << endl;
cout << "Happy birthday dear " << person << "!" << endl;
cout << "Happy birthday to you!" << endl;
}
```
.
.
.
.
.
## Calling a function.
Now that we have our `sing` function declared and defined, it is time to use it in `main`.
- To **call** the function we write `sing(argument)` and we pass in an **argument** for the parameter of the function.
- We must have the parentheses `(` and `)` to call a function, even if that function has no parameters!
```cpp
#include
#include
using namespace std;
void sing(string person);
int main() {
sing("Joe Bruin"); // Calling the function
sing("Oski the Bear"); // Calling the function
return 0;
}
void sing(string person) {
for (int i = 0; i < 10; ++i){ cout << "~ * ";} cout << endl;
cout << "Happy birthday to you!" << endl;
cout << "Happy birthday to you!" << endl;
cout << "Happy birthday dear " << person << "!" << endl;
cout << "Happy birthday to you!" << endl;
}
```
**Important.** The word **parameter** refers to the variable used in the function scope, while **argument** refers to the thing that you assign to the parameters.
- `"Joe Bruin"` is the argument.
- `string person` is the parameter of this `sing` function.
- Doing `sing("Joe Bruin")` assigns the argument `"Joe Bruin"` to the parameter `person`.
### Scope of a function.
But where does the parameter `string person` exist during all of this?
- Each time the function is called, a **function scope** is created. (Draw a dashed box to represent this!)
- And as the function scope is created, the first thing that happens is **each parameter variable is declared and assigned to the values given by the arguments**.
- The corresponding argument is assigned to the corresponding parameter in the list indicated by the function signature.
- When the function ends, each parameter and variable declared in this function scope is **destroyed**.
- Now, **unlike a typical scope with braces**, a function scope is different in that it **cannot** access variables outside of its function scope.
- So the best way to allow the function to use something from the outside is to have a parameter and pass the outside data in as an argument.
- (Note. There is something called global variables which functions can reach on the outside, but we will not discuss that.)
.
.
.
.
.
## A mystery -- An 1D automaton.
### Part 1. A mysterious rule90....
Let us write a function that is not a `void` function, but actually returns something out.
I have a mysterious function in mind, call it `rule90`. This function **transforms** a string into another string.
- It will take in a `string` consisting only of space character `' '` and the character `'a'`.
- Like `"aa a a aa aaaa a aaaaa"`
- Or `"aaaaaaaaaaaaaaaaaaaaaa"`
- Or `" a "`
- It will **return** a `string` according to the following rule: If the input parameter is `string s`:
- We return a `string t` that has the same length as `s`,
- The `0`-th index and the last index character of `t` is the same as `s`
- For index `i` character of `t`, where `i > 0` and `i < s.length() - 1` (so `i` is strictly in the middle)
- If `s.at(i-1)` and `s.at(i+1)` are *different*, then `t.at(i)` is the character `'a'`.
- Otherwise `t.at(i)` is the space character `' '`.
For example,
```
s = "aa a a a" becomes
t = "aaaa a"
```
Let us write it up! Note we use `return` keyword to return the desired output of this function.
```cpp
#include
#include
using namespace std;
// declare our function rule90 here. What is its function signature?
int main() {
cout << rule90("aa a a a") << endl; // If done right, we
// expect "aaaa a"
return 0;
}
// define our function rule90 here. Make it return a string
// using the return keyword.
```
### Part 2. What if we use it repeatedly...???
Here is something curious about `rule90`. Let us try putting back in `rule90` what it gave us, repeatedly so. Say do it `100` times. And we `cout` the result each time. To do this we should create a `string` variable to hold this value and all its future updates. This loop would do:
```cpp
string s = "aa a a a";
for (int i = 0 ; i < 100; ++i) {
cout << s << endl;
s = rule90(s);
}
```
Try different starting argument `string s`!
- Try very random ones like `string s = " a aaa a a a a aa a a a a"`
- What do you get with `string s = " a "`?
**Curious!**
---